package com.utils;

import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * 处理图片
 */
public class ImageUtils {

    // 常见的图片MIME类型
    private static final Set<String> IMAGE_MIME_TYPES = new HashSet<>(Arrays.asList(
            "image/jpeg", "image/pjpeg", "image/png", "image/gif", "image/bmp",
            "image/tiff", "image/webp", "image/vnd.microsoft.icon"
    ));

    // 常见的图片文件扩展名
    private static final Set<String> IMAGE_EXTENSIONS = new HashSet<>(Arrays.asList(
            "jpg", "jpeg", "png", "gif", "bmp", "tiff", "webp", "ico"
    ));

    /**
     * 判断给定的MultipartFile是否为安全的图片文件。
     *
     * @param file 要检查的MultipartFile
     * @return 如果文件是安全的图片文件，则返回true；否则返回false
     */
    public static boolean isSafeImageFile(MultipartFile file) {
        if (file.isEmpty()) {
            return false;
        }

        // 检查MIME类型
        String contentType = file.getContentType();
        if (contentType == null || !IMAGE_MIME_TYPES.contains(contentType.toLowerCase())) {
            return false;
        }

        // 检查文件扩展名
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null) {
            return false;
        }
        int dotIndex = originalFilename.lastIndexOf('.');
        if (dotIndex == -1) {
            return false;
        }
        String extension = originalFilename.substring(dotIndex + 1).toLowerCase();
        if (!IMAGE_EXTENSIONS.contains(extension)) {
            return false;
        }

        // 尝试读取图片内容以进一步验证
        try (InputStream inputStream = file.getInputStream()) {
            BufferedImage image = ImageIO.read(inputStream);
            return image != null;
        } catch (IOException e) {
            // 如果在读取文件时发生异常，则可能不是图片文件
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 保存MultipartFile到指定路径，并使用新文件名（无后缀名）。
     *
     * @param file          MultipartFile文件对象
     * @param savePath      文件保存的相对路径
     * @param newFileName   无后缀名的新文件名
     * @return              如果保存成功返回true，否则返回false
     */
    public static boolean saveMultipartFile(MultipartFile file, String savePath, String newFileName) {
        // 获取文件后缀名
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null) {
            return false;
        }
        int dotIndex = originalFilename.lastIndexOf('.');
        if (dotIndex == -1) {
            return false;
        }
        String fileExtension = originalFilename.substring(dotIndex);

        // 构建新文件的完整路径和文件名
        Path newFilePath = Paths.get(savePath, newFileName + fileExtension);

        // 确保保存路径的目录存在
        File dir = newFilePath.getParent().toFile();
        if (!dir.exists() && !dir.mkdirs()) {
            return false;
        }

        try {
            // 将MultipartFile内容保存到新文件中
            Files.copy(file.getInputStream(), newFilePath, StandardCopyOption.REPLACE_EXISTING);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 测量图片文件的长度和宽度，并返回一个整数数组，其中第一个元素是长度（高度），第二个元素是宽度。
     *
     * @param multipartFile 图片文件
     * @return 包含长度和宽度的整数数组，如果读取失败则返回null
     */
    public static Integer[] measureImageSize(MultipartFile multipartFile) {
        try {
            // 读取图片到BufferedImage对象中
            BufferedImage bufferedImage = ImageIO.read(multipartFile.getInputStream());

            // 获取图片的宽度和高度（在图像处理中，通常宽度在前，高度在后）
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();

            // 返回包含宽度和高度的数组
            return new Integer[]{height, width};
        } catch (IOException e) {
            e.printStackTrace();
            // 处理异常，返回null表示读取失败
            return null;
        }
    }

    // 删除文件的方法
    public static boolean deleteFile(File file) {
        // 检查文件是否存在
        if (file.exists()) {
            // 检查是否是一个文件
            if (file.isFile()) {
                // 删除文件
                return file.delete();
            } else {
                // 如果不是文件（即目录），则抛出异常或返回false
                System.out.println("指定的路径不是一个文件: " + file.getAbsolutePath());
                return false;
            }
        } else {
            // 文件不存在
            return false;
        }
    }
}
